package org.jinghouyu.wind.ftp;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.jinghouyu.windRP.Partition;
import org.jinghouyu.windRP.ResourceEntry;

public class FtpProxy implements InvocationHandler {

	private FtpClient client;
	
	private ResourceEntry<FtpClient> resourceEntry;
	
	private Partition<FtpClient> partition;
	
	private static final int SERVER_UNREACHED = 421;
	
	private static final int REMOTE_DISCONNECTED = 426;
	
	private FtpProxy(FtpClient client, Partition<FtpClient> partition) {
		this.client = client;
		FtpClient proxy = (FtpClient) Proxy.newProxyInstance(client.getClass().getClassLoader(), new Class[] {FtpClient.class}, this);
		resourceEntry = new ResourceEntry<FtpClient>(partition, proxy);
		this.partition = partition;
	}
	
	static ResourceEntry<FtpClient> proxy(FtpClient client, Partition<FtpClient> partition) {
		return new FtpProxy(client, partition).resourceEntry;
	}
	
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		String methodName = method.getName();
		if("close".equals(methodName)) {
			resourceEntry.release();
			return null;
		}
		try {
			return method.invoke(client, args);
		} catch(Throwable e) {
			if(e instanceof FtpException) {
				FtpException ftpException = (FtpException) e;
				int errorCode = ftpException.getErrorCode();
				switch(errorCode) {
				case SERVER_UNREACHED : 
					partition.getPool().releaseAndRemoveAll();
					break;
				case REMOTE_DISCONNECTED :
					resourceEntry.destroy();
					break;
				}
			}
			throw e;
		}
	}
}
